package com.eso.frame.core

import org.apache.log4j.Logger;
import com.eso.frame.InitialLoader
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware

/**
 * 系统初始化加载管理类
 * User: Noah.Rong
 * Version: 0.1,  2012-07-28 10:03
 */
class InitialLoaderManager implements ApplicationContextAware {
    private static Logger log = Logger.getLogger(InitialLoaderManager.class);

    ApplicationContext applicationContext;
    Map<String, InitialLoader> initialLoaderMap;

    void start() {
        log.info("start to initialize InitialLoader class ...");
        initialLoaderMap = applicationContext.getBeansOfType(InitialLoader.class);

        //对初始化加载器进行排序，实现顺序加载数据缓存
        Map.Entry[] sortedInitialLoaderMap = getSortedMapByValue(initialLoaderMap);
        sortedInitialLoaderMap.each {Map.Entry entry ->
            InitialLoader serviceLoader = (InitialLoader) entry.value;
            long start = System.currentTimeMillis();
            if (serviceLoader.isOnLoad()) {
                log.info("start to initLoad [" + entry + "] ...");
                serviceLoader.initLoad();
                log.info("initLoad [" + entry + "] finish. cost time:" + (System.currentTimeMillis() - start) + "ms");
            } else {
                log.info("the serviceLoader's [" + entry + "] isOnLoad value is false, so don't initLoad.");
            }
        }
        log.info("initialize InitialLoader finished");
    }

    public void reload(String serviceName) {
        initialLoaderMap.get(serviceName).reload();
    }


    /**
     * 根据Map的value值进行排序
     * @param loaderMap
     * @return
     */
    @SuppressWarnings("unchecked")
    def Map.Entry[] getSortedMapByValue(Map<String, InitialLoader> loaderMap) {
        Set set = loaderMap.entrySet();
        Map.Entry[] entries = (Map.Entry[]) set.toArray(new Map.Entry[set.size()]);

        Arrays.sort(entries, { Object arg1, Object arg2 ->

            InitialLoader o1 = (InitialLoader) ((Map.Entry) arg1).getValue();
            InitialLoader o2 = (InitialLoader) ((Map.Entry) arg2).getValue();

            return o1.getLoadOrder() - o2.getLoadOrder();

        } as Comparator<InitialLoader>);

        return entries;
    }
}
